File size: 4,812 Bytes
b2974e8
7119782
 
7e21d9b
7119782
fe997de
7e21d9b
7a83db7
7e21d9b
 
 
 
 
 
d743cd0
7e21d9b
 
 
 
 
fe997de
 
7e21d9b
7119782
7e21d9b
 
 
 
47e2fc4
 
53590af
 
 
f5ed2ae
 
 
 
 
 
b95b7b7
 
 
 
 
 
9deb76c
 
 
 
 
 
 
b95b7b7
 
9deb76c
b95b7b7
 
9deb76c
b95b7b7
e5bd9f1
9deb76c
47e2fc4
7119782
b95b7b7
 
47e2fc4
 
53590af
 
f5ed2ae
53590af
7119782
 
7a83db7
7119782
7a83db7
ba3ff9a
7119782
 
 
 
 
fe997de
188966c
7119782
 
ba3ff9a
7119782
 
b7d9073
 
ba3ff9a
7119782
b7d9073
 
ba3ff9a
7119782
b7d9073
 
ba3ff9a
b7d9073
 
 
ba3ff9a
b7d9073
 
 
7119782
 
 
 
 
 
f5ed2ae
bc5df64
37cf3dc
 
7119782
adc823d
 
71194e2
e5bd9f1
fe997de
47e2fc4
53590af
 
 
 
 
 
 
f5ed2ae
188966c
3dbc3bb
7119782
 
188966c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import streamlit as st
import pandas as pd
import requests
import base64

def get_backlinks(api_login, api_key, target_url, filters, include_subdomains):
    # Encoding credentials
    encoded_credentials = base64.b64encode(f"{api_login}:{api_key}".encode()).decode()

    # Setting headers with Basic Authentication
    headers = {
        'Authorization': f'Basic {encoded_credentials}'
    }

    # Prepare post data
    post_data = {
        0: {
            "target": target_url,
            "limit": 1000,
            "mode": "as_is",
            "filters": filters,
            "include_subdomains": include_subdomains  # Adding the include_subdomains filter
        }
    }

    # Making the API request
    response = requests.post("https://api.dataforseo.com/v3/backlinks/backlinks/live", json=post_data, headers=headers)

    # Log the full response for debugging
    st.text("API Response:")
    st.text(f"Response Status Code: {response.status_code}")
    st.text(f"Response Headers: {response.headers}")
    try:
        response_json = response.json()
        st.text(f"Response Body: {response_json}")
    except ValueError as e:
        st.text(f"Response Body: <Not a JSON response>\nError: {e}")

    # Check if the response contains 'results' key and handle the JSON structure appropriately
    if response.status_code == 200:
        response_data = response.json()
        
        # Debugging: Print out the keys of the response_data
        st.text(f"Keys in response JSON: {list(response_data.keys())}")

        if 'tasks' in response_data:
            # Assuming there is only one task and one result within each task
            task_result = response_data['tasks'][0]['result']
            if task_result and 'items' in task_result[0]:
                # The actual backlink items are nested within 'items'
                items = task_result[0]['items']
                st.text(f"First few items: {items[:5]}")  # Debugging line to show the items structure
                
                # Convert to DataFrame
                df = pd.json_normalize(items)
                return df
            else:
                st.error("Received empty 'result' from API or missing 'items'.")
                return None
        else:
            st.error(f"No 'tasks' key in response JSON. Full response: {response_data}")
            return None
    else:
        error_message = response.json().get('status_message', 'No specific error message provided')
        st.error(f"Error: Code: {response.status_code} Message: {error_message}")
        return None

def convert_df_to_csv(df):
    # Convert DataFrame to CSV
    return df.to_csv(index=False).encode('utf-8')

# Streamlit layout
st.sidebar.title("DataForSEO API Parameters")
api_login = st.sidebar.text_input("API Login", value="[email protected]")
api_key = st.sidebar.text_input("API Key", type="password")

# Filters input
url_from_not_contain = st.sidebar.text_input("URL from does not contain (comma-separated)")
is_lost = st.sidebar.checkbox("Is Lost", value=False)
dofollow = st.sidebar.checkbox("Dofollow", value=True)
backlink_spam_score = st.sidebar.slider("Backlink Spam Score ≤", 0, 100, 10)
page_from_language = st.sidebar.selectbox("Page From Language", ['en', 'other'])
include_subdomains = st.sidebar.checkbox("Include Subdomains", value=True)  # New filter

# Prepare filters for API call
filters = []

if url_from_not_contain:
    for url in url_from_not_contain.split(','):
        filters.append(["url_from", "not_like", url.strip()])
        filters.append("and")

if is_lost:
    filters.append(["is_lost", "=", is_lost])
    filters.append("and")

if dofollow:
    filters.append(["dofollow", "=", dofollow])
    filters.append("and")

filters.append(["backlink_spam_score", "<=", backlink_spam_score])
filters.append("and")
filters.append(["page_from_language", "=", page_from_language])

# Remove the last "and" if it's the last element
if filters and filters[-1] == "and":
    filters.pop()

# Main app layout
col1, col2 = st.columns(2)

with col1:
    st.header("Input")
    target_url = st.text_input("Enter the target URL")

generate_button = st.sidebar.button("Generate All")
reset_button = st.sidebar.button("Reset")

df = None

# Generate CSV and download button
if generate_button and target_url:
    df = get_backlinks(api_login, api_key, target_url, filters, include_subdomains)
    if df is not None:
        csv = convert_df_to_csv(df)
        st.download_button(
            label="Download data as CSV",
            data=csv,
            file_name='backlinks.csv',
            mime='text/csv',
        )
    else:
        st.error("Failed to generate CSV: No data returned from the API or data processing error.")

# Reset functionality
if reset_button:
    st.experimental_rerun()