Python爬虫
基础知识
请求头中最常见的一些重要内容(爬虫需要):
- User-Agent: 请求载体的身份标识(用啥发送的请求)
- Referer:防盗链(这才请求是从哪个页面来的?反爬会用到)
- cookie:本地字符串数据信息(用户登录信息,反爬的token)
响应头中一些重要的内容
- cookie:本地字符串数据信息(用户登录信息,反爬的token)
- 各种神奇的莫名其妙的字符串(这个需要经验了,一般都是token字样,防止各种攻击和反爬)
请求方式:
- GET:显示提交
- POST:隐式提交
正则表达式
元字符
元字符:具有固定含义的特殊符号
量词
贪婪匹配:尽可能多的去匹配结果
惰性匹配:尽可能少的去匹配结果
requests
import requests
url = "http://www.baidu.com"
resp = requests.get(url)
resp.encoding = "UTF-8"
print(resp.text)
*****************************************************************************************************
# post请求
import requests
url = "https://fanyi.baidu.com/sug"
# 携带的参数
data = {
"kw": input("请输入要翻译的内容:")
}
# 使用data=来传递参数
resp = requests.post(url, data=data)
print(resp.json()['data'])# 此时拿到的直接是python数据
*****************************************************************************************************
# get携带多个参数的请求 (单参时可直接拼接在url后面)
import requests
url = "https://movie.douban.com/j/new_search_subjects"
data = {
"sort": "U",
"range": "0,10",
"tags": "",
"start": "0",
"genres": "爱情"
}
headers = {
"Cookie":"bid=0ZT3o4Zkmgg; douban-fav-remind=1; __gads=ID=55cc9dab1692c695-22d35d04e8cc0002:T=1635416013:RT=1635416013:S=ALNI_MbDL_Ptl5d5LKAaZsn8HQCoKVNSZw; ll=\"118237\"; __utma=30149280.46741740.1635416015.1635416015.1637071437.2; __utmc=30149280; __utmz=30149280.1637071437.2.2.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmt=1; dbcl2=\"250194121:Mu1wx1M9P+A\"; ck=Y9QF; push_noty_num=0; push_doumail_num=0; __utmv=30149280.25019; __utmc=223695111; __utmt_t1=1; _pk_ref.100001.4cf6=["","",1637071489,\"https://www.douban.com/\"]; _pk_ses.100001.4cf6=*; _vwo_uuid_v2=D5207DF8A92B15C81C90BED014771BDFC|3ef9d8295d3791dbd3355ee1a1750b52; __utma=223695111.1487566936.1637071489.1637071489.1637071505.2; __utmb=223695111.0.10.1637071505; __utmz=223695111.1637071505.2.2.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; _pk_id.100001.4cf6=3e96079380d4c6e1.1637071489.1.1637071552.1637071489.; __utmb=30149280.24.8.1637071552091; RT=s=1637071948852&r=https://movie.douban.com/tag/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"
}
# 此处特别注意使用的是params,在post中使用的是data
resp = requests.get(url, params=data, headers=headers)
print(resp.json())
re使用讲解
import re
# result = re.findall("a","asdfadf")
# print(result)
# *******重点*******
# result = re.finditer(r"\d+","我今年18岁,我有2000000000元")
# for item in result: # 从迭代器中拿结果
# print(item.group()) # 从匹配到的结果中拿数据
# search 只匹配第一次匹配的内容
# result = re.search(r"\d+","我叫周杰伦,我今年3岁,我上4年4班")
# print(result) # <re.Match object; span=(9, 10)
# print(result.group()) # match='3'> # 3
#match 在匹配的时候,是从字符串的开头开始匹配的,类似在正则前面加入了^
# result = re.match(r"\d+","我叫周杰伦,我今年3岁,我上4年4班")
# print(result) #结果: None
# 预加载,提前把正则对象加载完毕
# obj = re.compile(r"\d+")
# # 直接把加载好的正则进行使用
# result = obj.findall("我叫周杰伦,我今年3岁,我上4年4班")
# print(result) # 结果 ['3', '4', '4']
# 想要提取数据时必须使用小括号括起来,可以单独取名字
# (?P<名字>正则表达式)
# 提取数据时使用group("名字")
s = """
<div class="西游记"><span id='10086'>中国移动</span></div>
<div class="西游记"><span id='10010'>中国联通</span></div>
"""
obj = re.compile(r"<span id='(?P<id>\d+)'>(?P<name>.*?)</span>")
result = obj.finditer(s)
for item in result:
print(item.group("id"))
print(item.group("name"))
bs4使用讲解
from bs4 import BeautifulSoup
html = """
<ul>
<li id="abc"><a href="www.baidu.com">周星驰</a></li>
</ul>
"""
#1. 初始化BeautifulSoup对象
page = BeautifulSoup(html,"html.parser")
# page.find("标签名",attrs={"属性":"值"}) # 查找某个元素,只会找到一个结果
# page.find_all("标签名",attrs={"属性":"值"}) # 找到一堆结果
li = page.find("li",attrs={"id":"abc"})
print(li) # <li id="abc"><a href="www.baidu.com">周星驰</a></li>
a = li.find("a")
print(a.text) # 周星驰
print(a.get("href")) # www.baidu.com
xpath
from lxml import etree
xml = """
<book>
<name>周杰伦</name>
</book>
"""
et = etree.XML(xml)
# result = et.xpath('/book') # /表示根节点
result = et.xpath('/book/name') # 在xpath中间的/表示的是儿子
result = et.xpath('/book/name/test()')[0] # text() 表示拿文本
result = et.xpath('/book//nick') # //表示的是所有子孙后代
result = et.xpath('book/*/nick/text()') # * 表示的是通配符
result = et.xpath('/book/author/nick[@class='jay']/text()') # []表示属性筛选. @属性名=值
result = et.xpath('/book/partner/nick/@id') #最后一个/表示拿到nick里面的id的内容 @属性 可以拿到属性值
print(result)
list列表中的字符串合并
strings = ["a","b","c"] result = "".join(strings) 最终会输出为 abc
pyquery
第三方代理
有时候访问请求过多时,网站会将我们的ip地址封掉,此时就需要第三方代理来进行爬虫了
代码如下:
import requests
def get_ip(): # 获取代理ip的方法
url = ""
resp = requests.get(url)
ip_lsit = resp.json()["data"]["ip_list"]
for item in ip_lsit:
yield item
def spider(): # 爬虫主程序
url = "www.baidu.com"
while 1:
try:
proxy_ip = next(gen)
proxy = {
"http": "http://" + proxy_ip,
"https": "https//" + proxy_ip
}
resp = requests.get(url, proxy_ip=proxy)
resp.encoding = "utf-8"
return resp.text
except:
print("报错了")
if __name__ == '__main__': # main 主进程
gen = get_ip()
for i in range(10):
spider()